#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import markdown

from com.chenxiaojie.dao.orm import create_args_string
from com.chenxiaojie.model.blog import Blog
from com.chenxiaojie.model.reply import Reply
from com.chenxiaojie.model.user import User
from com.chenxiaojie.mvc.error import APIPermissionError, APIValueError, APIResourceNotFoundError
from com.chenxiaojie.mvc.mvc import get, post
from com.chenxiaojie.mvc.page import page as Page


def get_page_index(page_str):
    p = 1
    try:
        p = int(page_str)
    except ValueError as e:
        pass
    if p < 1:
        p = 1
    return p


def text2html(text):
    lines = map(lambda s: '<p>%s</p>' % s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;'),
                filter(lambda s: s.strip() != '', text.split('\n')))
    return ''.join(lines)


@get('/')
async def index(*, page='1'):
    page_index = get_page_index(page)
    num = await Blog.findNumber('count(id)')
    page = Page(num, page_index=page_index)
    if num == 0:
        blogs = []
    else:
        blogs = await Blog.findAll(orderBy='created_at desc', limit=(page.offset, page.limit))
    return {
        '__template__': 'blogs.html',
        'page': page,
        'blogs': blogs
    }


@get('/blog/{id}.html')
async def get_blog(id):
    blog = await Blog.find(id)
    if blog is None:
        raise APIResourceNotFoundError('blog not found')
    replys = await Reply.findAll('blog_id=?', [id], orderBy='created_at desc')
    blog.creator = await User.find(blog.user_id)
    # blog.html_content = markdown.markdown(blog.content,
    #                                       extensions=['markdown.extensions.extra', 'markdown.extensions.codehilite',
    #                                                   'markdown.extensions.tables'])

    blog.html_content = markdown.markdown(blog.content, extensions=['markdown.extensions.extra'])
    reply_creator_ids = set()
    for reply in replys:
        reply.html_content = text2html(reply.content)
        reply_creator_ids.add(reply.user_id)

    reply_creator_ids = list(reply_creator_ids)
    if reply_creator_ids:
        reply_creators = await User.findAll(where="id in (" + create_args_string(len(reply_creator_ids)) + ")",
                                            args=reply_creator_ids)
        for reply in replys:
            for creator in reply_creators:
                if reply.user_id == creator.id:
                    reply.creator = creator

    return {
        '__template__': 'blog.html',
        'blog': blog,
        'replys': replys
    }


@post('/blog/{blog_id}/reply')
async def add_reply(blog_id, request, *, content):
    user = request.__user__
    if user is None:
        raise APIPermissionError('please login first')
    if not content or not content.strip():
        raise APIValueError('content')
    blog = await Blog.find(blog_id)
    if blog is None:
        raise APIResourceNotFoundError('blog')
    reply = Reply(blog_id=blog.id, user_id=user.id, content=content.strip())
    return await reply.insert()
